home *** CD-ROM | disk | FTP | other *** search
- #include "iff.h"
-
- #include<exec/libraries.h>
- #include<intuition/intuition.h>
- #include<utility/tagitem.h>
- #include<graphics/text.h>
- #include<graphics/rastport.h>
- #include<intuition/screens.h>
- #include<libraries/gadtools.h>
- #include<libraries/asl.h>
- #include<exec/memory.h>
-
- #include<string.h>
- #include<stdio.h>
-
- #include<clib/exec_protos.h>
- #include<clib/graphics_protos.h>
- #include<clib/intuition_protos.h>
- #include<clib/gadtools_protos.h>
- #include<clib/asl_protos.h>
- #include<clib/dos_protos.h>
-
- /* The library base global variables */
- /* (The different style of opening libraries requires these to be initialised to NULL) */
- struct Library* GfxBase = NULL;
- struct Library* IntuitionBase = NULL;
- struct Library* GadToolsBase = NULL;
- struct Library* AslBase = NULL;
- struct Library* DosBase = NULL;
- struct Library* IFFBase = NULL;
-
- /* The global handle on the palette gadget */
- struct Gadget* palgad = NULL;
- /* Global record of foreground pen */
- UBYTE pen;
- /* Global records of our windows */
- struct Window* drawwin = NULL;
- struct Window* toolwin = NULL;
- /* Global record of title bar height */
- int offtop;
- /* Global record of our menu strip */
- struct Menu* menustrip = NULL;
- /* Global record of the screen's visual information */
- APTR vinfo = NULL;
- /* Initialised structure declaration: describes 8pt Topaz font */
- struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
- /* Global record of our gadget list */
- struct Gadget* glist = NULL;
- /* Global record of our screen */
- struct Screen* scr = NULL;
- /* Global handles for our requesters */
- struct FileRequester* loadreq = NULL;
- struct FileRequester* savereq = NULL;
- /* Global handle for our bitmap */
- struct BitMap* bitmap = NULL;
-
- /* Need to give prototypes for our functions */
- int createAll();
- void freeAll();
- int openLibs();
- void closeLibs();
- int openScr();
- void closeScr();
- int createMenuStrip();
- void freeMenuStrip();
- int openToolWin();
- void closeToolWin();
- int openDrawWin();
- void closeDrawWin();
- int createGadgets();
- void freeGadgets();
- void handleIDCMP();
- int checkToolWin();
- void setFgPen(int);
- void doGadgetUp(UWORD, struct Gadget*);
- int doMenuPick(UWORD);
- void freeReqs();
- void load();
- void save();
- int createBitmap();
- void freeBitmap();
-
- /* Some constants for the position and size of our gadget */
- #define MYBUT_LEFT (10)
- #define MYBUT_TOP (5)
- #define MYBUT_WIDTH (80)
- #define MYBUT_HEIGHT (12)
- #define MYBUT_TEXT "Next Pen"
- #define MYBUT_ID (0)
-
- #define MYPAL_LEFT (170)
- #define MYPAL_TOP (1)
- #define MYPAL_WIDTH (109)
- #define MYPAL_HEIGHT (19)
- #define MYPAL_TEXT "Colour:"
- #define MYPAL_ID (1)
- #define MYPAL_DEPTH (4)
-
- /* The top gap required around the gadgets */
- #define MYTOPGAP (21)
-
- /* The initial pen colour */
- #define MYINITPEN (1)
-
- /* The size of our filename string */
- #define MAXFILENAME (300)
-
- /* The start of the program */
- void main()
- {
- /* Use a different style of opening libraries... */
- if(createAll())
- {
- /* Now do the real work */
- handleIDCMP();
- }
- /* Matched call to close libraries */
- freeAll();
- }
-
- int createAll()
- {
- return openLibs() && openScr() && createBitmap() && createMenuStrip() && createGadgets() && openToolWin() && openDrawWin();
- }
-
- void freeAll()
- {
- freeReqs();
- closeDrawWin();
- closeToolWin();
- freeGadgets();
- freeMenuStrip();
- freeBitmap();
- closeScr();
- closeLibs();
- }
-
- /* Try to open all the libraries -- return TRUE on success */
- int openLibs()
- {
- if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
- {
- printf("Error: could not open graphics.library\n");
- return FALSE;
- }
- if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
- {
- printf("Error: could not open intuition.library\n");
- return FALSE;
- }
- if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
- {
- printf("Error: could not open gadtools.library\n");
- return FALSE;
- }
- if((AslBase = OpenLibrary("asl.library",37)) == NULL)
- {
- printf("Error: could not open asl.library\n");
- return FALSE;
- }
- if((DosBase = OpenLibrary("dos.library",37)) == NULL)
- {
- printf("Error: could not open dos.library\n");
- return FALSE;
- }
- if((IFFBase = OpenLibrary("iff.library",23)) == NULL)
- {
- printf("Error: could not open iff.library\n");
- return FALSE;
- }
- return TRUE;
- }
-
- /* Close any open library */
- void closeLibs()
- {
- if(IFFBase)
- CloseLibrary(IFFBase);
- if(DosBase)
- CloseLibrary(DosBase);
- if(AslBase)
- CloseLibrary(AslBase);
- if(GadToolsBase)
- CloseLibrary(GadToolsBase);
- if(IntuitionBase)
- CloseLibrary(IntuitionBase);
- if(GfxBase)
- CloseLibrary(GfxBase);
- }
-
- /* Open screen and setup GadTools stuff */
- int openScr()
- {
- UWORD pens[] = { ~0 };
- /* Try to open a new screen with 16 colours (four bitplanes deep) */
- if(scr = OpenScreenTags(NULL,
- SA_Depth, 4,
- /* Enable 3D look by specifying SA_Pens */
- SA_Pens, pens,
- SA_Title, "Hello World Painter",
- TAG_DONE))
- {
- /* Get the visual info so GadTools can render the gadgets nicely */
- if(vinfo = GetVisualInfo(scr, TAG_DONE))
- /* Succeeded */
- return TRUE;
- else
- printf("Error: could not get visual info\n");
- }
- else
- printf("Error: could not create screen\n");
- /* Failed */
- return FALSE;
- }
-
- void closeScr()
- {
- if(vinfo)
- {
- FreeVisualInfo(vinfo);
- vinfo = NULL;
- }
- if(scr)
- {
- CloseScreen(scr);
- scr = NULL;
- }
- }
-
- /* Create the menu strip, using GadTools menu functions */
- int createMenuStrip()
- {
- /* The description of our menus */
- struct NewMenu mymenu[] =
- {
- { NM_TITLE, "Project", 0, 0, 0, 0,},
- { NM_ITEM, "Load", "L", 0, 0, 0,},
- { NM_ITEM, "Save", "S", 0, 0, 0,},
- { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
- { NM_ITEM, "Quit", "Q", 0, 0, 0,},
- { NM_TITLE, "Pen", 0, 0, 0, 0,},
- { NM_ITEM, "Next", "N", 0, 0, 0,},
- { NM_ITEM, "Prev", "P", 0, 0, 0,},
- { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
- { NM_ITEM, "Reset", "R", 0, 0, 0,},
- { NM_TITLE, "Tools", 0, 0, 0, 0,},
- { NM_ITEM, "Screen Bar", "C", CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
- { NM_ITEM, "Tool Bar", "T", CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
- { NM_END, NULL, 0, 0, 0, 0,},
- };
- if (menustrip = CreateMenus(mymenu, TAG_END))
- {
- if (LayoutMenus(menustrip, vinfo, TAG_END))
- /* Succeeded */
- return TRUE;
- else
- printf("Error: could not layout menus\n");
- }
- else
- printf("Error: could not create menu strip\n");
- /* Failed */
- return FALSE;
- }
-
- void freeMenuStrip()
- {
- if(menustrip)
- {
- FreeMenus(menustrip);
- menustrip = NULL;
- }
- }
-
- /* Actually open the windows, in the normal way */
- int openToolWin()
- {
- /* Extra protection -- only open if not already open */
- if(toolwin == NULL)
- {
- /* The minimal height of our tool window */
- int h = MYTOPGAP + offtop + scr->WBorBottom;
- /* Open our tool window */
- if(toolwin = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, scr->Height - h,
- /* Make the window sit in the bottom of the screen */
- WA_Width, scr->Width,
- WA_Height, h,
- WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR,
- WA_IDCMP, IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
- WA_Gadgets, glist,
- WA_CustomScreen, scr,
- WA_Title, "Tools",
- TAG_DONE, 0))
- {
- /* Attach menu strip to tool window, as well */
- if(SetMenuStrip(toolwin, menustrip))
- {
- /* Let GadTools refresh its bits of the tool window */
- GT_RefreshWindow(toolwin, NULL);
- return TRUE;
- }
- else
- printf("Error: could not attach menus to tool window\n");
- }
- else
- printf("Error: could not open tool window\n");
- }
- else
- printf("Warning: tool window already open\n");
- return FALSE;
- }
-
- void closeToolWin()
- {
- if(toolwin)
- {
- ClearMenuStrip(toolwin);
- CloseWindow(toolwin);
- toolwin = NULL;
- }
- }
-
- int openDrawWin()
- {
- /* Open our drawing window */
- if(drawwin = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- /* Make the window the same size as the screen */
- WA_Width, scr->Width,
- WA_Height, scr->Height,
- WA_Flags, WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_REPORTMOUSE | WFLG_SUPER_BITMAP,
- WA_IDCMP, IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK,
- WA_CustomScreen, scr,
- WA_SuperBitMap, bitmap,
- TAG_DONE, 0))
- {
- /* Clear our window, since our new bitmap may not be cleared already */
- SetRast(drawwin->RPort, 0);
- /* Set the drawing mode to draw only the foreground of text, not the background */
- SetDrMd(drawwin->RPort, JAM1);
- /* Attach menu strip to drawing window */
- if(SetMenuStrip(drawwin, menustrip))
- return TRUE;
- else
- printf("Error: could not attach menus to drawing window\n");
- }
- else
- printf("Error: could not open drawing window\n");
- return FALSE;
- }
-
- void closeDrawWin()
- {
- if(drawwin)
- {
- ClearMenuStrip(drawwin);
- CloseWindow(drawwin);
- drawwin = NULL;
- }
- }
-
- int createGadgets()
- {
- struct Gadget* gad;
- int offleft;
- struct NewGadget newgad;
- /* Start a GadTools gadget list */
- gad = CreateContext(&glist);
- /* The offsets of our window borders */
- offleft = scr->WBorLeft;
- offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
-
- /* Setup our first gadget */
- newgad.ng_TextAttr = &topazFont;
- newgad.ng_VisualInfo = vinfo;
- newgad.ng_LeftEdge = MYBUT_LEFT + offleft;
- newgad.ng_TopEdge = MYBUT_TOP + offtop;
- newgad.ng_Width = MYBUT_WIDTH;
- newgad.ng_Height = MYBUT_HEIGHT;
- newgad.ng_GadgetText = MYBUT_TEXT;
- newgad.ng_GadgetID = MYBUT_ID;
- newgad.ng_Flags = 0;
- /* Now create it and add it to our list */
- gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
-
- /* Setup our second gadget */
- /* (We can reuse newgad, and just change the different bits) */
- newgad.ng_LeftEdge = MYPAL_LEFT + offleft;
- newgad.ng_TopEdge = MYPAL_TOP + offtop;
- newgad.ng_Width = MYPAL_WIDTH;
- newgad.ng_Height = MYPAL_HEIGHT;
- newgad.ng_GadgetText = MYPAL_TEXT;
- newgad.ng_GadgetID = MYPAL_ID;
- newgad.ng_Flags = 0;
- /* Now create it and add it to our list */
- gad = CreateGadget( PALETTE_KIND, gad, &newgad,
- /* Initially selected pen */
- GTPA_Color, MYINITPEN,
- /* Depth: 2 to the power MYPAL_DEPTH colours */
- GTPA_Depth, MYPAL_DEPTH,
- /* Gadget will indicate selection */
- GTPA_IndicatorWidth, 16,
- TAG_DONE);
-
- /* Remember gadget pointer so we can affect it in message handler */
- palgad = gad;
- /* Success if we managed final allocation */
- return (gad != NULL);
- }
-
- void freeGadgets()
- {
- if(glist)
- {
- FreeGadgets(glist);
- glist = NULL;
- /* Reset palgad pointer, too */
- palgad = NULL;
- }
- }
-
- /* Our message handling code */
- void handleIDCMP()
- {
- char* text = "Hello World!";
- int going = TRUE;
- int drawing = FALSE;
- ULONG drawsig, toolsig, gotsig;
- drawsig = 1 << drawwin->UserPort->mp_SigBit;
- setFgPen(MYINITPEN);
- while(going)
- {
- struct IntuiMessage* intuimsg;
- /* Only include tool window signal mask if window is open */
- toolsig = toolwin ? 1 << toolwin->UserPort->mp_SigBit : 0;
- /* Wait for messages to arrive */
- gotsig = Wait(drawsig | toolsig);
- /* Messages have arrived: loop through all of them */
- /* Check messages from the drawing window first */
- if(gotsig & drawsig)
- {
- while(intuimsg = GT_GetIMsg(drawwin->UserPort))
- {
- /* Copy the important bits of the message */
- ULONG class = intuimsg->Class;
- UWORD code = intuimsg->Code;
- WORD mousex = intuimsg->MouseX;
- WORD mousey = intuimsg->MouseY;
- /* Reply when finished copying bits from message */
- GT_ReplyIMsg(intuimsg);
- /* Act on this message... */
- switch(class)
- {
- case IDCMP_MOUSEBUTTONS:
- switch(code)
- {
- case SELECTDOWN:
- drawing = TRUE;
- break;
- case SELECTUP:
- drawing = FALSE;
- break;
- }
- /* break; omitted so we draw on click, too */
- case IDCMP_MOUSEMOVE:
- if(drawing)
- {
- Move(drawwin->RPort, mousex, mousey);
- Text(drawwin->RPort, text, strlen(text));
- }
- break;
- case IDCMP_MENUPICK:
- going = doMenuPick(code);
- break;
- }
- }
- }
- /* Now check messages from the tool window */
- if(going && (gotsig & toolsig))
- {
- while(toolwin && (intuimsg = GT_GetIMsg(toolwin->UserPort)))
- {
- /* Copy the important bits of the message */
- ULONG class = intuimsg->Class;
- UWORD code = intuimsg->Code;
- APTR iaddr = intuimsg->IAddress;
- /* Reply when finished copying bits from message */
- GT_ReplyIMsg(intuimsg);
- /* Act on this message... */
- switch(class)
- {
- case IDCMP_CLOSEWINDOW:
- {
- struct MenuItem* item;
- /* Close tool window */
- closeToolWin();
- /* Unset menu check mark */
- /* First, remove menu strip from drawing window */
- ClearMenuStrip(drawwin);
- /* Menu 2, Item 1 is Tool Bar */
- item = ItemAddress(menustrip, FULLMENUNUM(2,1,0));
- /* Unset CHECKED flag */
- item->Flags &= ~CHECKED;
- /* Reattach menu strip to drawing window */
- ResetMenuStrip(drawwin,menustrip);
- break;
- }
- case IDCMP_REFRESHWINDOW:
- /* You *MUST* remember to ask for and handle these refresh messages */
- GT_BeginRefresh(toolwin);
- GT_EndRefresh(toolwin, TRUE);
- break;
- case IDCMP_GADGETUP:
- doGadgetUp(code, (struct Gadget*)iaddr);
- break;
- case IDCMP_MENUPICK:
- going = doMenuPick(code);
- break;
- }
- }
- }
- }
- }
-
- /* Set foreground pen of drawing window */
- void setFgPen(int value)
- {
- /* Wrap when reached the end of the palette gadget's colours */
- pen = value % (1<<MYPAL_DEPTH);
- /* Only set pen if window is open */
- if(drawwin)
- SetAPen(drawwin->RPort, pen);
- /* If the palette gadget has been made, update it with new pen value */
- if(palgad)
- GT_SetGadgetAttrs(palgad, toolwin, NULL, GTPA_Color, pen, TAG_DONE);
- }
-
- /* Process IDCMP_GADGETUP event */
- void doGadgetUp(UWORD code, struct Gadget* gad)
- {
- switch(gad->GadgetID)
- {
- case MYBUT_ID:
- /* Our button was clicked! Set foreground to next pen colour */
- setFgPen(pen+1);
- break;
- case MYPAL_ID:
- /* Our palette gadget was clicked! Set foreground to gadget colour */
- setFgPen(code);
- break;
- }
- }
-
- /* Process IDCMP_MENUPICK event */
- int doMenuPick(UWORD code)
- {
- UWORD menuCode, menuNumber, itemNumber;
- /* Loop over all the menu selections in the menu code */
- struct MenuItem* item;
- for(menuCode = code;
- menuCode != MENUNULL;
- menuCode = item->NextSelect)
- {
- item = ItemAddress(menustrip, menuCode);
- /* Extract the menu number and menu item number from the menu code */
- menuNumber = MENUNUM(menuCode);
- itemNumber = ITEMNUM(menuCode);
- /* Now decide what to do based on what menu item was selected */
- switch(menuNumber)
- {
- case 0: /* Project menu */
- /* Only one item: Quit */
- switch(itemNumber)
- {
- case 0: /* Load */
- load();
- break;
- case 1: /* Save */
- save();
- break;
- case 3: /* Quit (item 2 is the bar!) */
- return FALSE;
- }
- break;
- case 1: /* Pen menu */
- switch(itemNumber)
- {
- case 0: /* Next */
- setFgPen(pen+1);
- break;
- case 1: /* Prev */
- setFgPen(pen-1);
- break;
- case 3: /* Reset (item 2 is the bar!) */
- setFgPen(MYINITPEN);
- break;
- }
- break;
- case 2: /* Tools menu */
- switch(itemNumber)
- {
- case 0: /* Screen Bar */
- ShowTitle(scr, item->Flags & CHECKED);
- break;
- case 1: /* Tool Bar */
- /* Do the open or close */
- if(item->Flags & CHECKED)
- {
- /* If the open fails, stop immediately */
- if(!openToolWin())
- return FALSE;
- }
- else
- closeToolWin();
- break;
- }
- }
- }
- /* Keep going */
- return TRUE;
- }
-
- /* Open an ASL load file requester */
- void load()
- {
- /* Allocate the requester if we haven't already */
- if(loadreq == NULL)
- loadreq = (struct FileRequester*)AllocAslRequest(ASL_FileRequest,NULL);
- if(loadreq)
- {
- if(AslRequestTags(loadreq,
- ASLFR_TitleText, "Load File",
- ASLFR_Window, drawwin,
- ASLFR_Flags1, FRF_DOPATTERNS,
- ASLFR_InitialPattern, "#?.iff",
- TAG_DONE))
- {
- char filename[MAXFILENAME];
- /* Create complete filename from ASL's dir and file */
- strcpy(filename, loadreq->rf_Dir);
- if(AddPart(filename, loadreq->rf_File, MAXFILENAME))
- {
- IFFL_HANDLE handle;
- /* Try to open the IFF file */
- if(handle = IFFL_OpenIFF(filename, IFFL_MODE_READ))
- {
- LONG count;
- UWORD colortable[256];
- /* Get colour information and change screen colours */
- count = IFFL_GetColorTab(handle, colortable);
- LoadRGB4(&(scr->ViewPort), colortable, count);
- /* If we can load the picture, update window's display */
- if(IFFL_DecodePic(handle, bitmap))
- CopySBitMap(drawwin->WLayer);
- else
- printf("Error: could not decode IFF picture\n");
- IFFL_CloseIFF(handle);
- }
- else
- printf("Error: could not open IFF file\n");
- }
- else
- printf("Error: could not make filename\n");
- }
- /* else: requester was cancelled */
- }
- else
- printf("Error: could not allocate ASL (load) file request\n");
- }
-
- /* Open an ASL save file requester */
- void save()
- {
- /* Another way of saying "allocate if we haven't already" */
- if(savereq || (savereq = (struct FileRequester*)AllocAslRequest(ASL_FileRequest,NULL)))
- {
- if(AslRequestTags(savereq,
- ASLFR_TitleText, "Save File",
- ASLFR_Window, drawwin,
- ASLFR_Flags1, FRF_DOPATTERNS | FRF_DOSAVEMODE,
- ASLFR_InitialPattern, "#?.iff",
- ASLFR_InitialFile, "picture.iff",
- TAG_DONE))
- {
- char filename[MAXFILENAME];
- /* Create complete filename from ASL's dir and file */
- strcpy(filename, savereq->rf_Dir);
- if(AddPart(filename, savereq->rf_File, MAXFILENAME))
- {
- /* Make sure our bitmap is the same as the display */
- SyncSBitMap(drawwin->WLayer);
- /* Try saving our bitmap, using the screen's colours */
- if(IFFL_SaveBitMap(filename, bitmap,
- scr->ViewPort.ColorMap->ColorTable,
- IFFL_COMPR_BYTERUN1) == 0)
- printf("Error: could not write IFF picture\n");
- }
- else
- printf("Error: could not make filename\n");
- }
- /* else: requester was cancelled */
- }
- else
- printf("Error: could not allocate ASL (save) file request\n");
- }
-
- /* Free any requesters that may have been allocated */
- void freeReqs()
- {
- if(loadreq)
- {
- FreeAslRequest(loadreq);
- loadreq = NULL;
- }
- if(savereq)
- {
- FreeAslRequest(savereq);
- savereq = NULL;
- }
- }
-
- int createBitmap()
- {
- /* The MEMF_CLEAR flag is vital, since it zeroes the allocated memory. */
- /* Thus the pointers in the bitmap will be NULL, if we don't manage to */
- /* allocate them properly. */
- if(bitmap = AllocMem(sizeof(struct BitMap), MEMF_PUBLIC | MEMF_CLEAR))
- {
- int plane;
- InitBitMap(bitmap, scr->BitMap.Depth, scr->Width, scr->Height);
- for(plane = 0; plane < scr->BitMap.Depth; plane++)
- {
- bitmap->Planes[plane] = AllocRaster(scr->Width, scr->Height);
- if(bitmap->Planes[plane] == NULL)
- return FALSE;
- }
- /* If we get here, we succeeded. */
- return TRUE;
- }
- else
- return FALSE;
- }
-
- void freeBitmap()
- {
- if(bitmap)
- {
- int plane;
- for(plane = 0; plane < scr->BitMap.Depth; plane++)
- {
- if(bitmap->Planes[plane])
- FreeRaster(bitmap->Planes[plane], scr->Width, scr->Height);
- }
- FreeMem(bitmap, sizeof(struct BitMap));
- bitmap = NULL;
- }
- }
-